/*
 * Action.java
 */
package strips;

import java.util.ArrayDeque;

/**
 *
 * @author mire
 */
public class Action implements Goal {

    protected String name;
    protected int arity;
    protected ArrayDeque<Block> atributes;
    protected ArrayDeque<Predicate> prequisition;
    protected ArrayDeque<Predicate> delete;
    protected ArrayDeque<Predicate> add;

    public Action(String name, ArrayDeque<Block> atributes) {
        this.name = name;
        this.arity = atributes.size();
        this.atributes = atributes;
        this.prequisition = new ArrayDeque<Predicate>();
        this.delete = new ArrayDeque<Predicate>();
        this.add = new ArrayDeque<Predicate>();
    }

    public ArrayDeque<Predicate> getAdd() {
        return add;
    }

    public ArrayDeque<Block> getAtributes() {
        return atributes;
    }

    public ArrayDeque<Predicate> getDelete() {
        return delete;
    }

    public String getName() {
        return name;
    }

    public ArrayDeque<Predicate> getPrequisition() {
        return prequisition;
    }
    //na osnovu imena pupunjava uslove akcije

    public void calculateАction() {
        if (arity == 2) {
            ArrayDeque<Block> x = atributes.clone();
            x.removeLast();
            ArrayDeque<Block> y = atributes.clone();
            y.removeFirst();
            //assimilate
            if (name.equals(assimilate)) {
                prequisition.addLast(new Predicate(black, x));
                prequisition.addLast(new Predicate(white, y));
                prequisition.addLast(new Predicate(on, atributes.clone()));
                delete.addLast(new Predicate(white, y));
                add.addLast(new Predicate(black, y));
                return;
            }
            //stack
            if (name.equals(stack)) {
                prequisition.addLast(new Predicate(clear, y));
                prequisition.addLast(new Predicate(holding, x));
                delete.addLast(new Predicate(clear, y));
                delete.addLast(new Predicate(holding, x));
                add.addLast(new Predicate(armEmpty));
                add.addLast(new Predicate(on, atributes.clone()));
                return;
            }
            //unstack
            if (name.equals(unstack)) {
                prequisition.addLast(new Predicate(on, atributes.clone()));
                prequisition.addLast(new Predicate(clear, x));
                prequisition.addLast(new Predicate(armEmpty));
                delete.addLast(new Predicate(on, atributes.clone()));
                delete.addLast(new Predicate(armEmpty));
                add.addLast(new Predicate(clear, y));
                add.addLast(new Predicate(holding, x));
                return;
            }
        } else {
            ArrayDeque<Block> x = atributes.clone();
            //pickup
            if (name.equals(pickup)) {
                prequisition.addLast(new Predicate(clear, x));
                prequisition.addLast(new Predicate(onTable, x));
                prequisition.addLast(new Predicate(armEmpty));
                delete.addLast(new Predicate(onTable, x));
                delete.addLast(new Predicate(armEmpty));
                add.addLast(new Predicate(holding, x));
                return;
            }
            //putdown
            if (name.equals(putdown)) {
                prequisition.addLast(new Predicate(holding, x));
                delete.addLast(new Predicate(holding, x));
                add.addLast(new Predicate(onTable, x));
                add.addLast(new Predicate(armEmpty));
                return;
            }
        }
    }

    @Override
    public String toString() {
        String ret = name + "(" + atributes.peekFirst();
        if (atributes.size() > 1) {
            ret += "," + atributes.peekLast();
        }
        ret += ")";

        return ret;

    }

    public int getArity() {
        return arity;
    }
    //u sluchaju da smo dodatno saznali atribut

    public void changeUnkownAtribute(Block b) {
        if (atributes.peekFirst().getName().equals(unknown)) {
            atributes.removeFirst();
            atributes.addFirst(b);
        } else {
            atributes.removeLast();
            atributes.addLast(b);
        }
        prequisition.clear();
        delete.clear();
        add.clear();

        calculateАction();
    }
}
